/* NOTICE
    OpenJaWS - Open Java Weather Station
    
    Copyright (C) 2008 Grant Gardner <grant@lastweekend.com.au>
    
    OpenJaWS is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
NOTICE */

package au.com.lastweekend.openjaws.util;

import java.util.Arrays;

public class StringUtil {

    public interface DeepFormatter {

        Object[] formatArgs();
    }

    @SuppressWarnings("unchecked")
    /**
     * Crude way to handle nice array printing.
     */
    public static String toString(Object object) {

        String result;
        if (object.getClass().isArray()) {
            Class readingClass = object.getClass().getComponentType();
            if (Integer.TYPE.equals(readingClass)) {
                result = Arrays.toString((int[]) object);
            } else if (Long.TYPE.equals(readingClass)) {
                result = Arrays.toString((long[]) object);
            } else if (Double.TYPE.equals(readingClass)) {
                result = Arrays.toString((double[]) object);
            } else if (Float.TYPE.equals(readingClass)) {
                result = Arrays.toString((float[]) object);
            } else if (Character.TYPE.equals(readingClass)) {
                result = Arrays.toString((char[]) object);
            } else if (Boolean.TYPE.equals(readingClass)) {
                result = Arrays.toString((boolean[]) object);
            } else if (Short.TYPE.equals(readingClass)) {
                result = Arrays.toString((short[]) object);
            } else {
                result = Arrays.toString((Object[]) object);
            }
        } else {
            result = object.toString();
        }
        return result;
    }

    public static String nonNull(String s) {

        return s == null ? "" : s;
    }

    public static boolean isEmpty(String s) {

        return s == null || s.length() == 0;
    }

    public static String toHexBytes(byte[] buffer, int offset, int count) {

        StringBuffer strBuff = new StringBuffer();
        String sep = "";
        for (int i = 0; i < count; i++) {
            String hexString = String.format("%02x", buffer[i]);
            strBuff.append(sep);
            strBuff.append(hexString);
            sep = " ";
        }

        return strBuff.toString();
    }

    public static String deepFormat(String formatSpec, Object... args) {

        Object[] flatArgs = new Object[flattenFormatters(args)];
        flatten(args, flatArgs, 0);

        return String.format(formatSpec, flatArgs);

    }

    private static int flatten(Object[] args, Object[] flatArgs, int pos) {

        for (Object object : args) {
            if (object instanceof Object[]) {
                pos = flatten((Object[]) object, flatArgs, pos);
            } else {
                flatArgs[pos++] = object;
            }
        }

        return pos;
    }

    private static int flattenFormatters(Object[] args) {

        int size = 0;
        for (int i = 0; i < args.length; i++) {

            if (args[i] instanceof DeepFormatter) {
                args[i] = ((DeepFormatter) args[i]).formatArgs();
            }

            if (args[i] instanceof Object[]) {
                size = size + flattenFormatters((Object[]) args[i]);
            } else {
                size++;
            }
        }
        return size;
    }

}
